﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using System.Collections.Generic;

namespace imvs
{
    public static class LayerUtils
    {
        /// <summary>
        /// 创建新图层
        /// </summary>
        public static bool CreateLayer(string layerName, short colorIndex, LineWeight lineWeight, bool isFrozen = false, bool isOff = false, bool isLocked = false, Transaction tr = null)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            bool needCommit = false;
            if (tr == null)
            {
                tr = db.TransactionManager.StartTransaction();
                needCommit = true;
            }

            LayerTable layerTable = (LayerTable)tr.GetObject(
                Application.DocumentManager.MdiActiveDocument.Database.LayerTableId,
                OpenMode.ForWrite);

            if (!layerTable.Has(layerName))
            {
                LayerTableRecord layer = new LayerTableRecord
                {
                    Name = layerName,
                    Color = Color.FromColorIndex(ColorMethod.ByAci, colorIndex),
                    LineWeight = lineWeight,
                    IsPlottable = true,
                    IsFrozen = isFrozen,
                    IsOff = isOff,
                    IsLocked = isLocked
                };

                layerTable.UpgradeOpen();
                layerTable.Add(layer);
                tr.AddNewlyCreatedDBObject(layer, true);
                if (needCommit) { tr.Commit(); tr.Dispose(); }
                return true;
            }
            else
            {
                LayerTableRecord layer = (LayerTableRecord)tr.GetObject(
                    layerTable[layerName], OpenMode.ForWrite);

                layer.IsFrozen = isFrozen;
                layer.IsOff = isOff;
                layer.IsLocked = isLocked;
                layer.Color = Color.FromColorIndex(ColorMethod.ByAci, colorIndex);
                layer.LineWeight = lineWeight;
            }
            return false;
        }

        /// <summary>
        /// 获取当前图层名称
        /// </summary>
        public static string GetLayerName(ObjectId objId, Transaction tr = null)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            bool needCommit = false;
            if (tr == null)
            {
                tr = db.TransactionManager.StartTransaction();
                needCommit = true;
            }

            //using (Transaction tr = db.TransactionManager.StartTransaction())
            //{
            LayerTableRecord layer = (LayerTableRecord)tr.GetObject(
                objId,
                OpenMode.ForRead);
            string name = layer.Name;
            if (needCommit) { tr.Commit(); tr.Dispose(); }
            return name;
            //}
        }

        /// <summary>
        /// 检查图层是否可删除
        /// </summary>
        public static bool IsLayerDeletable(string layerName, Transaction tr = null)
        {

            // 系统图层检查
            if (layerName == "0" || layerName == "Defpoints")
                return false;

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            bool needCommit = false;
            if (tr == null)
            {
                tr = db.TransactionManager.StartTransaction();
                needCommit = true;
            }

            // 检查是否为当前图层

            if (layerName == GetLayerName(db.Clayer, tr))
            //if (layerName == (string)Application.GetSystemVariable("CLAYER"))
            {
                if (needCommit) { tr.Commit(); tr.Dispose(); }
                return false;
            }

            bool ret = false;
            // 检查是否有实体引用该图层
            using (BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead))
            {
                foreach (ObjectId id in modelSpace)
                {
                    Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
                    if (ent.Layer == layerName)
                    {
                        ret = false;
                        break;
                    }
                }
            }

            // 检查块定义中是否有引用
            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
            foreach (ObjectId blockId in blockTable)
            {
                BlockTableRecord blockDef = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                foreach (ObjectId id in blockDef)
                {
                    Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
                    if (ent.Layer == layerName)
                    {
                        ret = false;
                        break;
                    }
                }
            }

            if (needCommit) { tr.Commit(); tr.Dispose(); }
            {

            }
            return ret;
        }

        /// <summary>
        /// 强制删除图层
        /// </summary>
        public static void ForceDeleteLayer(string layerName, Transaction tr = null)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            bool needCommit = false;
            if (tr == null)
            {
                tr = db.TransactionManager.StartTransaction();
                needCommit = true;
            }

            LayerTable layerTable = (LayerTable)tr.GetObject(
                Application.DocumentManager.MdiActiveDocument.Database.LayerTableId,
                OpenMode.ForRead);

            if (layerTable.Has(layerName) && IsLayerDeletable(layerName, tr))
            {
                LayerTableRecord layer = (LayerTableRecord)tr.GetObject(
                    layerTable[layerName], OpenMode.ForWrite);
                layer.Erase();

                if (needCommit) { tr.Commit(); tr.Dispose(); }

            }
        }

        /// <summary>
        /// 删除图层上的所有实体
        /// </summary>
        public static int DeleteLayerEntities(string layerName, Transaction tr = null)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            bool needCommit = false;
            if (tr == null)
            {
                tr = db.TransactionManager.StartTransaction();
                needCommit = true;
            }

            int count = 0;

            // 处理模型空间
            using (BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite))
            {
                // 创建一个列表来存储遍历到的对象ID
                //List<ObjectId> entityIds = new List<ObjectId>();

                // 遍历模型空间中的所有对象
                foreach (ObjectId id in modelSpace)
                {
                    // 确保对象是Entity类型
                    Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                    if (ent != null && ent.Layer == layerName)
                    {
                        ent.UpgradeOpen();
                        ent.Erase();
                        count++;
                    }
                }
            }
            if (needCommit) { tr.Commit(); tr.Dispose(); }

            return count;
        }

        /// <summary>
        /// 设置图层可见性
        /// </summary>
        public static bool SetLayerVisibility(string layerName, bool isVisible, Transaction tr = null)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            bool needCommit = false;
            if (tr == null)
            {
                tr = db.TransactionManager.StartTransaction();
                needCommit = true;
            }

            LayerTable layerTable = (LayerTable)tr.GetObject(
                Application.DocumentManager.MdiActiveDocument.Database.LayerTableId,
                OpenMode.ForRead);

            if (layerTable.Has(layerName))
            {
                LayerTableRecord layer = (LayerTableRecord)tr.GetObject(
                    layerTable[layerName], OpenMode.ForWrite);

                layer.IsOff = !isVisible;

                if (needCommit) { tr.Commit(); tr.Dispose(); }
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取所有图层信息
        /// </summary>
        public static Dictionary<string, LayerInfo> GetAllLayers(Transaction tr = null)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            bool needCommit = false;
            if (tr == null)
            {
                tr = db.TransactionManager.StartTransaction();
                needCommit = true;
            }

            var layers = new Dictionary<string, LayerInfo>();
            LayerTable layerTable = (LayerTable)tr.GetObject(
                Application.DocumentManager.MdiActiveDocument.Database.LayerTableId,
                OpenMode.ForRead);

            foreach (ObjectId layerId in layerTable)
            {
                LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);
                layers.Add(layer.Name, new LayerInfo
                {
                    ColorIndex = layer.Color.ColorIndex,
                    LineWeight = layer.LineWeight,
                    IsOff = layer.IsOff,
                    IsFrozen = layer.IsFrozen,
                    IsLocked = layer.IsLocked
                });
            }

            if (needCommit) { tr.Commit(); tr.Dispose(); }
            return layers;
        }
    }

    public struct LayerInfo
    {
        public short ColorIndex { get; set; }
        public LineWeight LineWeight { get; set; }
        public bool IsOff { get; set; }
        public bool IsFrozen { get; set; }
        public bool IsLocked { get; set; }
    }

}
